/**
 * @file mq_client.h
 * @brief 对外提供订阅发布接口，对内管理mqclient对象
 * @author ypj
 * @date 2023年11月6日
 * @license MIT Apache2.0
 * Copyright (C), 2010-2023 Jouav Co., Ltd.
 */

#pragma once

#include <string>
#include "jo_sdk/jo_com.h"
#include "jo_sdk.h"
#include <pthread.h>
#include <mutex>
#include <map>

namespace jouav
{
/**
 *  @brief 类名 MQMgr
 *  @function MQ的管理类，单例，对外提供订阅和发布接口
 */
class MQMgr
{
public:
    /**
     * @brief 单例接口获取MQMgr的实例化对象
     * @return MQMgr实例化对象
     */
    static MQMgr& GetInstance();

    using sub_cb = std::function<int(const std::string& topic, const void* data, size_t sz)>;
    /**
     * @brief MQ初始化
     * @param strip MQ服务器IP，默认127.0.0.1
     * @return 0:成功 -1:失败
     */
    int Init(std::string strip = "127.0.0.1");

    /*!
     * @brief 添加订阅
     * @param topic_ 订阅主题
     * @param func_ 回调函数
     * @return int: 0:没有错误 -1:内部错误 65535：没有授权
     * @note 回调函数返回
     */
    virtual int Subscribe(const std::string& topic_, sub_cb func_);
    /*!
     * @brief 取消订阅
     * @param topic_ 取消订阅的Topic
     * @return int: 0:没有错误 -1:内部错误 65535：没有授权
     */
    virtual int UnSubscribe(const std::string& topic_);

    /*!
    * @brief 发布消息
    * @param topic_ 发布主题
    * @param data_ 数据
    * @param len_ 长度 ，-1失败
    * @return int: 0:没有错误 -1:内部错误 65535：没有授权
    */
    virtual int Publish(const std::string& topic_, const void* data_, size_t len_);
private:
    MQMgr() {}

private:
    std::recursive_mutex mutex_;
    std::map<std::string, int> map_sub_fd_; //<topic, fd>
    jo_sdk::env_handle_t uav_env_ = nullptr;
    jo_sdk::jo_com_raw_t com_t_ = nullptr;
    int init_flag = false; //初始化标志
};

}// namespace jouav
